﻿namespace BluetoothDemo.Internal
{
    public class PrinterInstance
    {
        private static PrinterType PrinterType { get; set; } = PrinterType.i80mm;
       

        public static async Task PrintAsync(string texto)
        {
            try
            {
                await VerificarBluetooth();
                await FonteNormal();
                await EspacoPadrao();
                await Esquerda();
                await WriteAsync(texto);
                await CloseAsync();
            }
            catch (Exception erro)
            {
                throw erro;
            }
        }

        public static async Task EncerrarAsync() => await CloseAsync();

        public static async Task<int> PrintLineAsync()
        {
            int ret = -1;

            try
            {
                await VerificarBluetooth();

                await FonteNormal();
                ret = await Traco();
                await CloseAsync();
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        /// <summary>
        /// 跳出打印
        /// </summary>
        /// <param name="quantidadeQuebra"></param>
        /// <returns></returns>
        public static async Task<int> PrintBreak(int quantidadeQuebra)
        {
            int ret = -1;

            try
            {
                await VerificarBluetooth();

                await FonteNormal();
                ret = await Quebra(quantidadeQuebra);
                await CloseAsync();
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        #region Métodos de apoio para executar na impressora

        private static async Task VerificarBluetooth()
        {
            if (PrinterManage.CurrentBluetoothClient == null)
                throw new Exception("需要打开连接才能开始使用打印机");

            if (!await PrinterManage.ConnectAsync())
                throw new Exception("无法通过蓝牙连接");

            await Task.Delay(0);
        }

        private static async Task<int> FonteNormal()
        {
            int ret = -1;

            try
            {
                string comando = (((char)0x1B) + string.Empty) + (((char)0x21) + string.Empty) + (((char)0x00) + string.Empty);
                await PrinterManage.SendAsync(comando);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> EspacoPadrao()
        {
            int ret = -1;

            try
            {
                string comando = (((char)0x1B) + string.Empty) + (((char)0x32) + string.Empty) + (((char)0x0D) + string.Empty);

                await PrinterManage.SendAsync(comando);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> WriteAsync(string texto)
        {
            int ret = -1;

            try
            {
                await PrinterManage.SendAsync(texto);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> WriteAsync(byte[] buffer, int offset, int count)
        {
            int ret = -1;

            try
            {
                await PrinterManage.SendAsync(buffer, offset, count);

                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> Esquerda()
        {
            int ret = -1;

            try
            {
                string comando = (((char)0x1B) + string.Empty) + (((char)0x61) + string.Empty) + (((char)0x00) + string.Empty);
                await PrinterManage.SendAsync(comando);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> CloseAsync()
        {
            int ret = -1;

            try
            {
                string comando = "\r\n";//((char)0x0A) + string.Empty;

                await PrinterManage.SendAsync(comando);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> Quebra(int qtdeQuebras)
        {
            int ret = -1;

            try
            {
                string comando = string.Empty;

                for (int i = 0; i < qtdeQuebras; i++)
                    comando += ((char)0x0A);

                await PrinterManage.SendAsync(comando);
                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> Espaco(int qtdeQuebras)
        {
            int ret = -1;

            try
            {
                string comando = string.Empty;

                for (int i = 1; i <= qtdeQuebras; i++)
                    comando += " ";

                if (!string.IsNullOrEmpty(comando))
                {
                    await PrinterManage.SendAsync(comando);
                    ret = 1;
                }
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        private static async Task<int> Traco()
        {
            int ret = -1;

            try
            {
                string comando = string.Empty;

                if (PrinterType == PrinterType.i80mm)
                    comando = "________________________________________________\n";
                else
                    comando = "________________________________\n";

                await PrinterManage.SendAsync(comando);

                ret = 1;
            }
            catch (Exception erro)
            {
                throw erro;
            }

            return ret;
        }

        #endregion;
    }
}
